package com.riteny.common.log;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
import ch.qos.logback.core.util.FileSize;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Riteny
 * 2020/11/4  16:53
 */
public class CommonLoggerFactory {

    private static final Map<String, Logger> loggers = new HashMap<>();

    public static Logger getLogger(String name) {

        Logger logger = loggers.get(name);
        if (logger != null) {
            return logger;
        }

        synchronized (CommonLoggerFactory.class) {
            logger = loggers.get(name);
            if (logger != null) {
                return logger;
            }
            logger = createLogger(name);
            loggers.put(name, logger);
        }

        return logger;
    }

    public static Logger createLogger(String loggerName) {

        CommonLogConfigEntity configEntity = CommonLogProperties.get(loggerName);

        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();

        RollingFileAppender<ILoggingEvent> rollingFileAppender = new RollingFileAppender<>();
        rollingFileAppender.setContext(loggerContext);
        rollingFileAppender.setAppend(true);
        rollingFileAppender.setName(loggerName + "LogAppender");
        rollingFileAppender.setFile(configEntity.getBaseDir() + "/" + loggerName + ".log");

        SizeAndTimeBasedRollingPolicy rollingPolicy = new SizeAndTimeBasedRollingPolicy<>();
        rollingPolicy.setFileNamePattern(configEntity.getBaseDir() + "/" + loggerName + ".%d{yyyy-MM-dd}.%i.log");
        rollingPolicy.setMaxHistory(configEntity.getMaxHistory());
        rollingPolicy.setContext(loggerContext);
        rollingPolicy.setParent(rollingFileAppender);
        rollingPolicy.setMaxFileSize(FileSize.valueOf(configEntity.getMaxFileSize()));
        rollingPolicy.setCleanHistoryOnStart(true);
        rollingPolicy.start();
        rollingFileAppender.setRollingPolicy(rollingPolicy);

        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %logger{50} %msg%n");
        encoder.setCharset(Charset.forName("UTF-8"));
        encoder.setContext(loggerContext);
        encoder.start();
        rollingFileAppender.setEncoder(encoder);
        rollingFileAppender.start();

        Logger logger = loggerContext.getLogger(loggerName);
        logger.addAppender(rollingFileAppender);

        return logger;
    }

    public static void registerLogger(String loggerName, String baseDir, Integer maxHistory, String maxFileSize) {
        CommonLogProperties.put(loggerName, baseDir, maxHistory, maxFileSize);
    }
}
